package com.gaokuo.es;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.util.Arrays;
import java.util.stream.IntStream;

/**
 * 模板、索引操作
 *
 * @author gaokuo
 */
@Slf4j
public class BaseTest {

    RestHighLevelClient client = new RestHighLevelClient(
            RestClient.builder(new HttpHost("10.10.20.112", 9200, "http"))
    );
    ObjectMapper mapper = new ObjectMapper();

    @Test
    public void createIndices() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("person");
        Settings settings = Settings.builder().put("index.number_of_shards", 1).build();
        request.settings(settings);
        String mapping = "{\"properties\":{\"name\":{\"type\":\"keyword\"},\"age\":{\"type\":\"integer\"},\"birthday\":{\"format\":\"yyy-MM-dd HH:mm:ss.SSS||epoch_millis||yyy-MM-dd HH:mm:ss\",\"type\":\"date\"},\"sex\":{\"type\":\"keyword\"},\"friendArr\":{\"type\":\"keyword\"},\"say\":{\"type\":\"text\",\"analyzer\": \"standard\"}}}";
        request.mapping(
                mapping,
                XContentType.JSON
        );
        CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);
        boolean acknowledged = response.isAcknowledged();
        log.info("acknowledged：{}", acknowledged);
    }

    @Test
    public void delIndices() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("*");
        AcknowledgedResponse response = client.indices().delete(request, RequestOptions.DEFAULT);
        boolean acknowledged = response.isAcknowledged();
        log.info("acknowledged：{}", acknowledged);
    }

    @Test
    public void add() throws IOException {
        IndexRequest request = new IndexRequest();
        request.index("person");
        Person person = new Person();
        String personStr = mapper.writeValueAsString(person);
        request.source(personStr, XContentType.JSON);
        log.info("{}", request);
        IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
        log.info("seqNo{},primaryTerm:{}",indexResponse.getSeqNo(),indexResponse.getPrimaryTerm());
        log.info("resp：{}", indexResponse.getResult());
    }

    @Test
    public void addBatch() throws IOException {
        BulkRequest request = new BulkRequest();
        IntStream.range(1, 10).forEach(i -> {
            try {
                request.add(new IndexRequest().index("person").source(mapper.writeValueAsString(new Person()), XContentType.JSON));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        });
        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
        BulkItemResponse[] items = bulk.getItems();
        for (BulkItemResponse item : items) {
            log.info("seqNo{},primaryTerm:{}",item.getResponse().getSeqNo(),item.getResponse().getPrimaryTerm());
        }
        log.info("resp：{}", bulk.getTook());
    }

    @Test
    public void getById() throws IOException {
        GetRequest request = new GetRequest();
        request.index("person").id("lr1vgX4Bh640GEarnWhT");
        GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
        log.info("seqNo{},primaryTerm:{}",documentFields.getSeqNo(),documentFields.getPrimaryTerm());
        log.info("{}",documentFields.getSourceAsString());
    }
    @Test
    public void search() throws IOException {
        SearchRequest request = new SearchRequest();
        request.indices("person");
        request.source(new SearchSourceBuilder().from(0).size(1).fetchSource("name",null));
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        log.info("结果集{}",Arrays.asList(search.getHits().getHits()));
        log.info("total:{}",search.getHits().getTotalHits());
    }

    /**
     * 局部更新
     */
    @Test
    public void update() throws IOException {
        UpdateRequest request = new UpdateRequest("person","oL2WgX4Bh640GEarWGht");
        String personStr = mapper.writeValueAsString(new Person());
        request.doc(personStr,XContentType.JSON);
        request.detectNoop();
        UpdateResponse response = client.update(request, RequestOptions.DEFAULT);
        log.info("{}",response.getGetResult());
    }
    /**
     * 全部更新  相当于删除添加
     */
    @Test
    public void put() throws IOException {
        IndexRequest request = new IndexRequest();
        request.index("person").id("oL2WgX4Bh640GEarWGht");
        Person person = new Person();
        String personStr = mapper.writeValueAsString(person);
        request.source(personStr, XContentType.JSON);
        log.info("{}", request);
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        log.info("seqNo{},primaryTerm:{}",response.getSeqNo(),response.getPrimaryTerm());
        log.info("resp：{}", response.getResult());
    }
    @Test
    public void del() throws IOException {
        DeleteRequest request = new DeleteRequest();
        request.index("person").id("oL2WgX4Bh640GEarWGht");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        log.info("seqNo{},primaryTerm:{}",response.getSeqNo(),response.getPrimaryTerm());
        log.info("resp：{}", response.getResult());
    }
    @Test
    public void delBatch() throws IOException {
        BulkRequest request = new BulkRequest();
        request.add(new DeleteRequest().index("person").id("oL2WgX4Bh640GEarWGht"));
        BulkResponse bulk = client.bulk(request, RequestOptions.DEFAULT);
        BulkItemResponse[] items = bulk.getItems();
        for (BulkItemResponse item : items) {
            log.info("{}",item.getResponse().getResult());
            log.info("seqNo{},primaryTerm:{}",item.getResponse().getSeqNo(),item.getResponse().getPrimaryTerm());
        }
        log.info("resp：{}", bulk.getTook());
    }
}
